#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QDebug>
#include <QImage>
#include <QColor>
#include <QPixmap>
#include <QFileDialog>
#include <algorithm>
#include<QLayout>
#include<QVBoxLayout>
#include<QLabel>
#include<QPushButton>
#include<QFileDialog>
#include<QCamera>
#include<QCameraViewfinder>
#include<QCameraImageCapture>
#include<QCameraInfo>

extern char result='r';
extern char rStatus='f';

float arrO[24]={0.56,0.78,1.00,0.33,
                  0.11,0.33,0.56,0.11,
                  0.33,0.56,0.56,0.56,
                  0.33,0.33,0.33,0.33,
                  1.00,1.00,0.56,1.00,
                  0.56,0.56,0.56,0.56};
float arrX[24]={0.56,0.56,0.56,1.00,
                1.00,0.56,0.56,0.56,
                0.56,1.00,1.00,0.56,
                0.33,0.56,0.33,0.33,
                0.56,0.56,0.78,0.56,
                0.56,0.56,0.56,0.33};
float arr[24]={};
int ii=0;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QList<QCameraInfo> infos = QCameraInfo::availableCameras();
    foreach(QCameraInfo info, infos){
        qDebug()<<info.description()<<info.deviceName();
        ui->comboBox->addItem(info.deviceName());
    }
    m_pCamera = new QCamera("@device:pnp:\\\\?\\root#image#0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\\global",this);
    m_pViewfinder = new QCameraViewfinder(this);
    m_pImageCapture = new QCameraImageCapture(m_pCamera);
    this->m_pViewfinder->setGeometry(0,400,320,180);
    m_pImageCapture->
    setCaptureDestination(QCameraImageCapture::CaptureToFile);
    m_pCamera->setCaptureMode(QCamera::CaptureStillImage);
    m_pCamera->setViewfinder(m_pViewfinder);

    connect(ui->button1,SIGNAL(clicked()),m_pImageCapture,SLOT(capture()));
    connect(ui->button2,SIGNAL(clicked()),this,SLOT(exitBtnResponded()));
    connect(m_pImageCapture,SIGNAL(imageCaptured(int,QImage)),
            this,SLOT(cameraImageCapture(int, QImage)));
    connect(ui->pushButton_carmera,SIGNAL(clicked()),this,SLOT(on_pushButton_carmera_clicked()));
    m_pCamera->start();


    double img[Nmax][Nmax];

    int F[6][3][3]={//模板一
        {
            {1,-1,-1,},
            {-1,1,-1,},
            {-1,-1,1,},

        },
        {
            {1,-1,1,},
            {-1,1,-1,},
            {1,-1,1,},
        },
        {
            {-1,-1,1,},
            {-1,1,-1,},
            {1,-1,-1,},
        },
        {
             {-1,1,-1,},
             {-1,1,-1,},
             {-1,1,-1,},
        },
        {
              {-1,-1,-1,},
              {1,1,1,},
              {-1,-1,-1,},
        },
        {
              {-1,1,-1,},
              {1,1,1,},
              {-1,1,-1,},
        },
    };
    int F1[6][3][3]={//模板二
        {
            {1,0,0,},
            {0,1,0,},
            {0,0,1,},
        },
        {
            {1,0,1,},
            {0,1,0,},
            {1,0,1,},
        },
        {
            {0,0,1,},
            {0,1,0,},
            {1,0,0,},
        },
        {
            {0,1,0,},
            {0,1,0,},
            {0,1,0,},
        },
        {
            {0,0,0,},
            {1,1,1,},
            {0,0,0,},
        },
        {
            {0,1,0,},
            {1,1,1,},
            {0,1,0,},
        },

    };
    Ft Feat[6];
    Ft Feat1[6];
    double timg[Nmax][Nmax];
    double tmp_img[Nmax][Nmax];
    for(int i = 0 ; i < Nmax ; i ++ )
        for(int j = 0 ; j < Nmax ; j ++ )
            tmp_img[i][j] = -1.0;
    //选择图片
    QString str = QFileDialog::getOpenFileName(this,"选择图片","/","textfile(*.jpg *.png);;All file(*.*)");
//    QString str = "D:/QtProject/图库/X.png";
    pix = QPixmap(str);
    image = pix.toImage();//格式转换
    int len = Nmax;
    //image转换成二值图
    Bitchange(img,&image,240);
//    Thin2(img,len);
//    QString savepath =QFileDialog::getSaveFileName(this,"save Capture","Capture","Image png(*.png);;Image jpg(*.jpg);;Image bmp(*.bmp)");
//    if(!savepath.isEmpty())
//    {
//        image.save(savepath);
//        qDebug()<<"***********Successful***********";
//    }

    //三个模板，依次进行卷积池化
    for(int i = 0 ; i < 6 ; i ++ ){
        Feat[i].cnt  = 0;
        for(int j = 0 ; j < 3 ; j ++ ){
            for(int k = 0 ; k < 3 ; k ++ ){
                Feat[i].val[j][k] = F1[i][j][k];
                Feat[i].cnt += (F[i][j][k]==1)?1:0;
            }
        }
        for(int j = 0 ; j < len ; j ++ ){
            for(int k = 0 ; k < len ; k ++ ){
                timg[j][k] = img[j][k];
            }
        }

        Smaller(timg,&Feat[i],len);
        //合并三个特征结果
        Merge(tmp_img,timg,9);
    }
//    Print(tmp_img,9);
    len = 9;
    //细化数组
    Thin2(tmp_img,len);
//    Print(tmp_img,9);

    //寻找特征值
    for(int i = 0 ; i < 6 ; i ++ ){
        Feat[i].cnt = Feat1[i].cnt = 0;
        for(int j = 0 ; j < 3 ; j ++ ){
            for(int k = 0 ; k < 3 ; k ++ ){
                Feat[i].val[j][k] = F1[i][j][k];
                Feat1[i].val[j][k] = F[i][j][k];
                Feat[i].cnt += (F[i][j][k]==1)?1:0;
                Feat1[i].cnt++;
            }
        }
        for(int j = 0 ; j < len ; j ++ ){
            for(int k = 0 ; k < len ; k ++ ){
                timg[j][k] = tmp_img[j][k];
            }
        }

        Node ans;
        findvalues(timg,&Feat[i],&Feat1[i],len,&ans);
//        printf("Feat = %d cnt = %d\n",i+1,Feat[i].cnt);
        //输出特征值
//        printf("第%d个特征值矩阵：\n");
        ans.show();
        for(int i = 0 ; i < 2 ; i ++ ){
            for(int j = 0 ; j < 2 ; j ++ ){
               arr[ii]=ans.val[i][j];
                ii++;
            }
        }
    }
}

MainWindow::~MainWindow()
{
    delete ui;


}
void MainWindow::findvalues(double image[Nmax][Nmax],Ft* Feat,Ft* Feat1,int len,Node* ans)
{

    len = Convolution(image, Feat1, len);
//    printf("************cnn,len = %d************\n",len);
//    Print(image,len);

    //激活一
    ReLU(image, len, 0.0);
//    printf("************ReLU,len = %d************\n",len);
//    Print(image,len);

    //池化三
    len = Pooling(image, len);
//    printf("************pool,len = %d************\n",len);
//    Print(image,len);

    //池化四
    len = Pooling(image, len);
//    printf("************pool,len = %d************\n",len);
//    Print(image,len);


    for(int i = 0 ; i < 2 ; i ++ ){
        for(int j = 0 ; j < 2 ; j ++ ){
            ans->val[i][j] = image[i][j];
        }
    }
}

//过程一【利用特征模板一（0-1模板）】：42*42图片->卷积->池化->第一种二值化->卷积->池化->第二种二值化->得到9*9数组
void MainWindow::Smaller(double image[Nmax][Nmax], MainWindow::Ft *Feat, int len)
{
    //卷积一
    len = Convolution(image, Feat, len);
//    printf("************cnn,len = %d************\n",len);
//    Print(image,len);

    //池化一
    len = Pooling(image, len);
//    printf("************pool,len = %d************\n",len);
//    Print(image,len);

    //第一种二值化一
    bitChange(image, len, 0.55);
//    printf("************bitchange,len = %d************\n",len);
//    Print(image,len);

    //卷积二
    len = Convolution(image, Feat, len);
//    printf("************cnn,len = %d************\n",len);
//    Print(image,len);

    //池化二
    len = Pooling(image, len);
//    printf("************pool,len = %d************\n",len);
//    Print(image,len);

    //第二种二值化二
    bitChange1(image, len, 0.55);
//    printf("************bitchange,len = %d************\n",len);
    //    Print(image,len);
}

//对数组进行合并,参数（最终合并image数组，参与合并数组，数组大小）
void MainWindow::Merge(double tmp_img[Nmax][Nmax], double timg[Nmax][Nmax], int len)
{
    for(int i = 0 ; i < len ; i ++ )
        for(int j = 0 ; j < len ; j ++ ){
            if(timg[i][j] == 1.0) tmp_img[i][j] = 1.0;
        }
}

//对数组进行卷积,参数（image数组，模板结构体，数组大小）
int MainWindow::Convolution(double image[Nmax][Nmax], Ft *Feat, int len)
{
    double Matr[Nmax][Nmax];

    //卷积
    for(int i = 1 ; i < len-1 ; i ++ ){
        for(int j = 1 ; j < len-1 ; j ++ ){
            Matr[i-1][j-1] = 0.0;
            for(int x = -1 ; x <= 1 ; x ++ ){
                for(int y = -1 ; y <= 1 ; y ++ ){
                    if(i+x >= 0 && i+x < len && j+y >= 0 && j+y < len){
                        Matr[i-1][j-1] += (1.0*image[i+x][j+y]*Feat->val[x+1][y+1]);
                    }
                }
            }
            Matr[i-1][j-1]=Matr[i-1][j-1]/(1.0*Feat->cnt);
        }
    }
    for(int i = 0 ; i < len-2 ; i ++ ){
        for(int j = 0 ; j < len-2 ; j ++ ){
            image[i][j] = Matr[i][j];
        }
    }
    return len-2;
}

//对数组进行池化,参数（image数组，数组大小）
int MainWindow::Pooling(double image[Nmax][Nmax], int len)
{
    //池化
    for(int i = 0 ; i < len ; i ++ ){
        for(int j = 0 ; j < len ; j ++ ){
            image[i/2][j/2] = std::max(image[i/2][j/2],image[i][j]);
            image[i][j] = 0.0;
        }
    }
    return (len+1)/2;
}

//对数组进行激活，参数（image数组，数组大小，激活阈值）
//小于阈值，将值为0.0
void MainWindow::ReLU(double image[Nmax][Nmax], int len,double hold)
{
    //激活
    for(int i = 0 ; i < len ; i ++ ){
        for(int j = 0 ; j < len ; j ++ ){
            if(image[i][j] < hold) image[i][j] = 0.0;
        }
    }
}

//打印数组，参数（image数组，数组大小）
void MainWindow::Print(double image[Nmax][Nmax], int len)
{
    //打印
//    printf("len = %d\n",len);
    for(int i = 0 ; i < len ; i ++ ){
        for(int j = 0 ; j < len ; j ++ ){
//            if(image[i][j] == 1.0)
            printf("%.2lf,",image[i][j]);
        }
        printf("\n");
    }
}

//将处理完数组二值化，参数（image数组，数组大小，阈值（0.0-1.0））
//小于阈值，将值为0.0，大于阈值，将值为1.0
void MainWindow::bitChange(double image[Nmax][Nmax], int len, double hold)
{
    //二值化
    for(int i = 0 ; i < len ; i ++ ){
        for(int j = 0 ; j < len ; j ++ ){
            if(image[i][j] < hold) image[i][j] = 0.0;
            else image[i][j] = 1.0;
        }
    }
}

//将处理完数组二值化，参数（image数组，数组大小，阈值（0.0-1.0））
//小于阈值，将值为-1.0，大于阈值，将值为1.0
void MainWindow::bitChange1(double image[Nmax][Nmax], int len, double hold)
{
    //二值化
    for(int i = 0 ; i < len ; i ++ ){
        for(int j = 0 ; j < len ; j ++ ){
            if(image[i][j] < hold) image[i][j] = -1.0;
            else image[i][j] = 1.0;
        }
    }
}

char MainWindow::compare()
{
    float num=0;
    for(int i=0;i<24;i++)
    {
        num+=(arr[i]-arrX[i])*(arr[i]-arrX[i]);
    }
    if(num<2)
    {
//        qDebug()<<"是x！";
        //printf("是x！");
        return 'x';
    }

    num=0;
    for(int i=0;i<24;i++)
    {
        num+=(arr[i]-arrO[i])*(arr[i]-arrO[i]);
    }
    if(num<2)
     {
//        qDebug()<<"是o！";
        //printf("是o！");
        return 'o';
     }
    else
    {
        qDebug()<<"对不起超过能力范围！";
        //printf("对不起超过能力范围！");
        return '#';
    }

}

//图像二值化，将img图片,转换成0-1数组
//参数（image数组，图片指针，二值化阈值（0-255））
//小于阈值，将值为0.0，大于阈值，将值为1.0
void MainWindow::Bitchange(double image[Nmax][Nmax],QImage *img,int hold)
{
//    qDebug()<<"***Bit Change***"<<hold;
    QColor color;
    int r;
    for(int i = 0 ; i < img->width() ; i ++ ){
        for(int j = 0 ; j < img->height() ; j ++ ){
            color = img->pixel(i,j);
            r = color.red();
            if(r >= hold)
                image[i][j] = 0.0;
            else
                image[i][j] = 1.0;
        }
    }
}
QImage *MainWindow::Graychange(QImage *image)//灰度转换
{
    QImage* newImage = new QImage(image->width(),image->height(),QImage::Format_ARGB32);
    QColor color;
    int r,g,b;
    for(int i = 0 ; i < image->width() ; i ++ ){
        for(int j = 0 ; j < image->height() ; j ++ ){
            color = image->pixel(i,j);
            r = color.red();
            g = color.green();
            b = color.blue();
            int tmp_ave = (r+g+b)/3;
            newImage->setPixelColor(i,j,QColor(tmp_ave,tmp_ave,tmp_ave));
        }
    }
    return newImage;
}

QImage *MainWindow::Bitchange3(QImage *image)//二值化
{
    int hold = ui->horizontalSlider->value();
    qDebug()<<"***Bit Change***"<<hold;
    QImage* newImage = new QImage(image->width(),image->height(),QImage::Format_ARGB32);
    QColor color;
    int r,g,b;
    for(int i = 0 ; i < image->width() ; i ++ ){
        for(int j = 0 ; j < image->height() ; j ++ ){
            color = image->pixel(i,j);
            r = color.red();
            g = color.green();
            b = color.blue();
            if(r >= hold)
                newImage->setPixelColor(i,j,QColor(255,255,255));
            else
                newImage->setPixelColor(i,j,QColor(0,0,0));
        }
    }
    return newImage;
}



QImage *MainWindow::Gausschange(QImage *image)//高斯滤波
{
    int hold = ui->horizontalSlider->value();
    QImage* newImage = new QImage(image->width(),image->height(),QImage::Format_ARGB32);
    QColor color;
    int gauss[3][3]={{1,2,1,},{2,4,2,},{1,2,1,},};
    int sum = 0 ;
    for(int i = 0 ; i < 3 ; i ++ )
        for(int j = 0 ; j < 3 ; j ++ ){
            sum+=gauss[i][j];
        }
    int r,g,b;
    for(int i = 1 ; i < image->width()-1 ; i ++ ){
        for(int j = 1 ; j < image->height()-1 ; j ++ ){
            r = g = b =0;
            for(int x = -1 ; x <= 1 ; x ++ )
                for(int y = -1 ; y <= 1 ; y ++ ){
                    color = image->pixel(i+x,j+y);
                    r += color.red()*gauss[x+1][y+1];
                    g += color.green()*gauss[x+1][y+1];
                    b += color.blue()*gauss[x+1][y+1];
                }
            r = qBound(0,r/sum,255);
            g = qBound(0,g/sum,255);
            b = qBound(0,b/sum,255);
            newImage->setPixelColor(i,j,QColor(r,g,b));
//            if((r+g+b)/3 > hold)
//                newImage->setPixelColor(i,j,QColor(255,255,255));
//            else
//                newImage->setPixelColor(i,j,QColor(0,0,0));
        }
    }
    return newImage;
}



QImage *MainWindow::findEdge(QImage *image)//二值化提取边缘
{
    QImage* newImage = new QImage(image->width(),image->height(),QImage::Format_ARGB32);
    QColor color,color_tmp;
    int ed[8][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
    int r,g,b;
    for(int i = 1 ; i < image->width()-1 ; i ++ )
        for(int j = 1 ; j < image->height()-1 ; j ++ )
            newImage->setPixelColor(i,j,QColor(255,255,255));
    for(int i = 1 ; i < image->width()-1 ; i ++ ){
        for(int j = 1 ; j < image->height()-1 ; j ++ ){
            color = image->pixel(i,j);
            if(color.red() == 0){
                for(int k = 0 ; k < 8 ; k ++ ){
                    color = image->pixel(i+ed[k][0],j+ed[k][1]);
                    if(color.red() == 255){
                        newImage->setPixelColor(i+ed[k][0],j+ed[k][1],QColor(0,0,0));
                    }
                }
            }
        }
    }
    for(int i = 1 ; i < image->width()-1 ; i ++ ){
        for(int j = 1 ; j < image->height()-1 ; j ++ ){
            color = image->pixel(i,j);
            color_tmp = newImage->pixel(i,j);
            if(color_tmp.red() == 0 && color.red() == 0){
                newImage->setPixelColor(i,j,QColor(255,255,255));
            }
        }
    }
    return newImage;
}

QImage *MainWindow::midchange(QImage *image)//中值滤波
{
    QImage* newImage = new QImage(image->width(),image->height(),QImage::Format_ARGB32);
    QColor color;
    int coo[9];
    int cnt = 0 ;
    int r,g,b;
    for(int i = 1 ; i < image->width()-1 ; i ++ ){
        for(int j = 1 ; j < image->height()-1 ; j ++ ){
            cnt = 0;
            for(int x = -1 ; x <= 1 ; x ++ )
                for(int y = -1 ; y <= 1 ; y ++ ) {
                    color = image->pixel(i+x,j+y);
                    coo[cnt++] = color.red();
                }
            std::sort(coo,coo+9);
            r = g = b = qBound(0,coo[4],255);
            newImage->setPixelColor(i,j,QColor(r,g,b));
        }
    }
    return newImage;
}

QImage *MainWindow::findEdge_by_direction(QImage *image)//梯度边缘提取
{
    int hold = ui->horizontalSlider_FindEdge->value();
    QImage* newImage = new QImage(image->width(),image->height(),QImage::Format_ARGB32);
    QColor color,color_tmp;
    int ed[8][2]={{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1}};
    int d[8];
    int mmax;
    for(int i = 1 ; i < image->width()-1 ; i ++ ){
        for(int j = 1 ; j < image->height()-1 ; j ++ ){
            newImage->setPixelColor(i,j,QColor(255,255,255));
        }
    }
    for(int i = 1 ; i < image->width()-1 ; i ++ ){
        for(int j = 1 ; j < image->height()-1 ; j ++ ){
            color = image->pixel(i,j);
            mmax = 0;
            for(int k = 0 ; k < 8 ; k ++ ){
                color_tmp = image->pixel(i+ed[k][0],j+ed[k][1]);
                if(color.red() > color_tmp.red()){
                    d[k] = color.red() - color_tmp.red();
                }
                else{
                    d[k] = color_tmp.red() - color.red();
                }
                mmax = std::max(mmax,d[k]);
            }
            if(mmax < hold) continue;
            for(int k = 0 ; k < 8 ; k ++ ){
                color_tmp = image->pixel(i+ed[k][0],j+ed[k][1]);
                if(color.red() > color_tmp.red()){
                    if(mmax == color.red() - color_tmp.red())
                        newImage->setPixelColor(i+ed[k][0],j+ed[k][1],QColor(0,0,0));
                }
                else{
                    if(mmax == color_tmp.red() - color.red())
                        newImage->setPixelColor(i+ed[k][0],j+ed[k][1],QColor(0,0,0));
                }
            }
        }
    }
    return newImage;
}




void   MainWindow::Thin2(double img[Nmax][Nmax],int len){
    int clc = 1;
    int image[Nmax][Nmax]={0};
    int num,w,e,nw,n,ne,sw,s,se;
    for(int i = 0 ; i < len ; i ++ ){
        for(int j = 0 ; j < len ; j ++ ){
            if(img[i][j] == -1.0 ) image[i][j] = 0;
            else if(img[i][j] == 1.0) image[i][j] = 1;
        }
    }
    bool next = true;
    while(clc > 0){
        clc = 0;
        next = true;
        for(int i = 1 ; i < len-1 ; i ++ ){
            for(int j = 1 ; j < len-1 ; j ++ ){
                if(!next) next = true;
                else if(image[i][j] == 1){
                    w = image[i][j-1];
                    e = image[i][j+1];
                    if((w == 0) || (e == 0)){
                        nw = image[i-1][j-1];
                        n  = image[i-1][j];
                        ne = image[i-1][j+1];
                        sw = image[i+1][j-1];
                        s  = image[i+1][j];
                        se = image[i+1][j+1];
                        num = (nw==1?0:1)+(n==1?0:1)*2+(ne==1?0:1)*4+(w==1?0:1)*8+(e==1?0:1)*16+(sw==1?0:1)*32+(s==1?0:1)*64+(se==1?0:1)*128;
                        if (table_erase[num] == 1){//基于查找表
//                            qDebug()<<"**********";
                            image[i][j] = 0;
                            next = false;
                            clc++;
                        }
                    }
                }
            }
        }
        next = true;
        for(int j = 1 ; j < len-1 ; j ++ ){
            for(int i = 1 ; i < len-1 ; i ++ ){
                if(!next) next = true;
                else if(image[i][j] == 1){
                    n = image[i-1][j];
                    s = image[i+1][j];
                    if((n == 0) || (s == 0)){
                        nw = image[i-1][j-1];
                        ne = image[i-1][j+1];
                        w  = image[i][j-1];
                        e  = image[i][j+1];
                        sw = image[i+1][j-1];
                        se = image[i+1][j+1];
                        num = (nw==1?0:1)+(n==1?0:1)*2+(ne==1?0:1)*4+(w==1?0:1)*8+(e==1?0:1)*16+(sw==1?0:1)*32+(s==1?0:1)*64+(se==1?0:1)*128;
                        if (table_erase[num]==1){//基于查找表
//                            qDebug()<<"**********"<<num<<i<<j;
                            image[i][j] = 0;
                            next = false;
                            clc++;
                        }
                    }
                }
            }
        }
    }
    for(int i = 0 ; i < len ; i ++ ){
        for(int j = 0 ; j < len ; j ++ ){
            if(image[i][j] == 0 ) img[i][j] = -1.0;
            else if(image[i][j] == 1) img[i][j] = 1.0;
        }
    }
    for(int i = 0 ; i < len ; i ++ ){
        for(int j = 0 ; j < len ; j ++ ){
            printf("%.2lf,",img[i][j]);
        }
        printf("\n");
    }
}



void MainWindow::findvalues1(int image[][100],Ft* Feat,int len,Node* ans)
{
    double cnnMatr1[2][100][100]={0};

    //特征

    //卷积
    for(int i = 0 ; i < len ; i ++ ){
        for(int j = 0 ; j < len ; j ++ ){
            cnnMatr1[0][i][j] = cnnMatr1[1][i][j] = -1;
        }
    }
    for(int i = 1 ; i < len-1 ; i ++ ){
        for(int j = 1 ; j < len-1 ; j ++ ){
            cnnMatr1[0][i][j] = 0;
            for(int x = 0 ; x < 3 ; x ++ ){
                for(int y = 0 ; y < 3 ; y ++ ){
                    cnnMatr1[0][i][j] += (1.0*image[i+x-1][j+y-1]*Feat->val[x][y]);
                }
            }
            cnnMatr1[0][i][j]/=(9.0);
        }
    }
    for(int i = 0 ; i < len ; i ++ ){
        for(int j = 0 ; j < len ; j ++ ){
            printf("%.2lf,",cnnMatr1[0][i][j]);
        }
        printf("\n");
    }

    //池化
    len = len-2;
    bool flag = true;
    while(len > 2){
        printf("len = %d\n",len);
        for(int i = 0 ; i <= len+1 ; i ++ ){
            for(int j = 0 ; j <= len+1 ; j ++ ){
                cnnMatr1[flag][i][j]=-1.0;
            }
        }
        for(int i = 1 ; i <= len ; i ++ ){
            for(int j = 1 ; j <= len ; j ++ ){
                cnnMatr1[flag][(i+1)/2][(j+1)/2] = std::max(cnnMatr1[flag][(i+1)/2][(j+1)/2],cnnMatr1[!flag][i][j]);
            }
        }
        len = (len+1)/2;
//        for(int i = 1 ; i <= len ; i ++ ){
//            for(int j = 1 ; j <= len ; j ++ ){
//                printf("%.2lf,",cnnMatr1[flag][i][j]);
//            }
//            printf("\n");
//        }
        flag = !flag;
    }
    for(int i = 1 ; i <= len ; i ++ ){
        for(int j = 1 ; j <= len ; j ++ ){
            ans->val[i-1][j-1] = cnnMatr1[!flag][i][j];
        }
    }
}

void MainWindow::toMatr(QImage *image, int img[100][100])
{
    QColor color;
    for(int i = 0 ; i < image->width() ; i ++ ){
        for(int j = 0 ; j < image->height() ; j ++ ){
            color = image->pixel(i,j);
            if(color.red() == 255) img[i][j] = -1;
            else img[i][j] = 1;
        }
    }
    for(int i = 0 ; i < image->width() ; i ++ ){
        for(int j = 0 ; j < image->height() ; j ++ ){
            printf("%d,",img[i][j]);
        }
        printf("\n");
    }
}

QImage *MainWindow::thin(QImage *image)
{
    int clc = 1;
    QImage* newImage = new QImage(image->width(),image->height(),QImage::Format_ARGB32);
    QColor color,color_tmp;
    int num,w,e,nw,n,ne,sw,s,se;
    bool next = true;

    for(int i = 0 ; i < image->width() ; i ++ )
        for(int j = 0 ; j < image->height() ; j ++ )
            newImage->setPixelColor(i,j,image->pixelColor(i,j));


    while(clc > 0){
        clc = 0;
        next = true;
        for(int i = 1 ; i < image->width()-1 ; i ++ ){
            for(int j = 1 ; j < image->height()-1 ; j ++ ){
                if(!next){next = true;continue;};
                color = newImage->pixelColor(i,j);
                if(color.red() == 0){
                    color_tmp = newImage->pixelColor(i,j-1);
                    w = color_tmp.red();
                    color_tmp = newImage->pixelColor(i,j+1);
                    e = color_tmp.red();
                    if((w == 255) || (e == 255)){
//                    if(true){
                        color_tmp = newImage->pixelColor(i-1,j-1);
                        nw = color_tmp.red();
                        color_tmp = newImage->pixelColor(i-1,j);
                        n  = color_tmp.red();
                        color_tmp = newImage->pixelColor(i-1,j+1);
                        ne = color_tmp.red();
                        color_tmp = newImage->pixelColor(i+1,j-1);
                        sw = color_tmp.red();
                        color_tmp = newImage->pixelColor(i+1,j);
                        s  = color_tmp.red();
                        color_tmp = newImage->pixelColor(i+1,j+1);
                        se = color_tmp.red();
                        num = nw/255+(n/255)*2+(ne/255)*4+(w/255)*8+(e/255)*16+(sw/255)*32+(s/255)*64+(se/255)*128;
                        if (table_erase[num] == 1){//基于查找表
//                            qDebug()<<num<<table_erase[num]<<nw<<n<<ne<<w<<e<<sw<<s<<se;
                            newImage->setPixelColor(i,j,QColor(255,255,255));
                            clc++;
                            next = false;
                        }
                    }
                }
            }
        }
        next = true;
        for(int j = 1 ; j < image->height()-1 ; j ++ ){
            for(int i = 1 ; i < image->width()-1 ; i ++ ){
                if(!next) {next = true;continue;};
                color = newImage->pixelColor(i,j);
                if(color.red() == 0){
                    color_tmp = newImage->pixelColor(i-1,j);
                    n = color_tmp.red();
                    color_tmp = newImage->pixelColor(i+1,j);
                    s = color_tmp.red();
                    if((n == 255) || (s == 255)){
//                        if(true){
                        color_tmp = newImage->pixelColor(i-1,j-1);
                        nw = color_tmp.red();
                        color_tmp = newImage->pixelColor(i-1,j+1);
                        ne = color_tmp.red();
                        color_tmp = newImage->pixelColor(i,j-1);
                        w  = color_tmp.red();
                        color_tmp = newImage->pixelColor(i,j+1);
                        e  = color_tmp.red();
                        color_tmp = newImage->pixelColor(i+1,j-1);
                        sw = color_tmp.red();
                        color_tmp = newImage->pixelColor(i+1,j+1);
                        se = color_tmp.red();
                        num = nw/255+(n/255)*2+(ne/255)*4+(w/255)*8+(e/255)*16+(sw/255)*32+(s/255)*64+(se/255)*128;
                        if (table_erase[num]==1){//基于查找表
//                            qDebug()<<num<<table_erase[num]<<nw<<n<<ne<<w<<e<<sw<<s<<se;
                            newImage->setPixelColor(i,j,QColor(255,255,255));
                            clc++;
                            next = false;
                        }
                    }
                }
            }
        }

    }
    return newImage;
}

void MainWindow::Init()
{
    QList<QCameraInfo> infos = QCameraInfo::availableCameras();
    foreach(QCameraInfo info, infos){
        qDebug()<<info.description()<<info.deviceName();
        ui->comboBox->addItem(info.deviceName());
    }
    m_pCamera = new QCamera("@device:pnp:\\\\?\\root#image#0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\\global",this);
    m_pViewfinder = new QCameraViewfinder(this);
    m_pImageCapture = new QCameraImageCapture(m_pCamera);
    this->m_pViewfinder->setGeometry(0,400,320,180);
    m_pImageCapture->
    setCaptureDestination(QCameraImageCapture::CaptureToFile);
    m_pCamera->setCaptureMode(QCamera::CaptureStillImage);
    m_pCamera->setViewfinder(m_pViewfinder);

    connect(ui->button1,SIGNAL(clicked()),m_pImageCapture,SLOT(capture()));
    connect(ui->button2,SIGNAL(clicked()),this,SLOT(exitBtnResponded()));
    connect(m_pImageCapture,SIGNAL(imageCaptured(int,QImage)),
            this,SLOT(cameraImageCapture(int, QImage)));
    connect(ui->pushButton_carmera,SIGNAL(clicked()),this,SLOT(on_pushButton_carmera_clicked()));
    m_pCamera->start();

}




void MainWindow::on_pushButton_addPicture_clicked()
{
    qDebug()<<"***add a apicture***";
    QString str = QFileDialog::getOpenFileName(this,"选择图片","/","textfile(*.jpg);;C file(*.png);;All file(*.*)");
    ui->label_filePathName->setText(str.toUtf8());
    pix = QPixmap(str);
    ui->label_addPicture->setGeometry(0,0,200,200);
    pix.scaled(ui->label_addPicture->size(),Qt::KeepAspectRatio);
    ui->label_addPicture->setScaledContents(true);
    ui->label_addPicture->setPixmap(pix);
}

void MainWindow::on_pushButton_grayChange_clicked()
{
    qDebug()<<"***change to gray picture***";
    image = pix.toImage();//格式转换
    QImage* newImage = Graychange(&image);
    pix1 = pix.fromImage(*newImage);
    ui->label_grayChange->setGeometry(200,0,200,200);
    pix1.scaled(ui->label_grayChange->size(),Qt::KeepAspectRatio);
    ui->label_grayChange->setScaledContents(true);
    ui->label_grayChange->setPixmap(pix1);
}

void MainWindow::on_pushButton_bitChange3_clicked()
{
    qDebug()<<"***change to bit picture***";
    image1 = pix1.toImage();//格式转换
    QImage* newImage = Bitchange3(&image1);
    pix2 = pix.fromImage(*newImage);
    ui->label_bitChange->setGeometry(400,0,200,200);
    pix2.scaled(ui->label_bitChange->size(),Qt::KeepAspectRatio);
    ui->label_bitChange->setScaledContents(true);
    ui->label_bitChange->setPixmap(pix2);
}

void MainWindow::on_horizontalSlider_valueChanged(int value)
{
    ui->spinBox->setValue(ui->horizontalSlider->value());
    on_pushButton_bitChange3_clicked();
}


void MainWindow::on_spinBox_valueChanged(int arg1)
{
    ui->horizontalSlider->setValue(ui->spinBox->value());
    on_pushButton_bitChange3_clicked();
}

void MainWindow::on_pushButton_gaussChange_clicked()
{
    qDebug()<<"***change to gauss picture***";
    image2 = pix1.toImage();//格式转换
    QImage* newImage = midchange(&image2);
    pix3 = pix.fromImage(*newImage);
    ui->label_gaussChange->setGeometry(0,200,200,200);
    pix3.scaled(ui->label_gaussChange->size(),Qt::KeepAspectRatio);
    ui->label_gaussChange->setScaledContents(true);
    ui->label_gaussChange->setPixmap(pix3);
}

void MainWindow::on_pushButton_findEdge_clicked()
{
    qDebug()<<"***find Edge***";
    image2 = pix1.toImage();//格式转换
    QImage* newImage = findEdge_by_direction(&image2);
    pix4 = pix.fromImage(*newImage);
    ui->label_findEdge->setGeometry(200,200,200,200);
    pix4.scaled(ui->label_findEdge->size(),Qt::KeepAspectRatio);
    ui->label_findEdge->setScaledContents(true);
    ui->label_findEdge->setPixmap(pix4);
}

void MainWindow::on_horizontalSlider_FindEdge_valueChanged(int value)
{
    ui->spinBox__FindEdge->setValue(ui->horizontalSlider_FindEdge->value());
    on_pushButton_findEdge_clicked();
}

void MainWindow::on_spinBox__FindEdge_valueChanged(const QString &arg1)
{
    ui->horizontalSlider_FindEdge->setValue(ui->spinBox__FindEdge->value());
    on_pushButton_findEdge_clicked();
}
void MainWindow::Print()
{
    int len;
    for(int i=0;i<len;i++)
        for(int j=0;j<len;j++)
        {
            printf("%5.2f",img[i][j]);
        }
}
void MainWindow::on_pushButton_cnn_clicked()
{

    rStatus = 't';
    qDebug()<<"***find values***";
    image3 = pix2.toImage();//格式转换,二值化图片
    QImage* newImage = thin(&image3);
    pix5 = pix.fromImage(*newImage);//细化图片
    ui->label_thin->setGeometry(700,350,300,300);
    pix5.scaled(ui->label_thin->size(),Qt::KeepAspectRatio);
    ui->label_thin->setScaledContents(true);
    ui->label_thin->setPixmap(pix5);

//    int ii=0;
//    int len = Nmax;
//    int F[6][3][3]={//模板一
//        {
//            {1,-1,-1,},
//            {-1,1,-1,},
//            {-1,-1,1,},

//        },
//        {
//            {1,-1,1,},
//            {-1,1,-1,},
//            {1,-1,1,},
//        },
//        {
//            {-1,-1,1,},
//            {-1,1,-1,},
//            {1,-1,-1,},
//        },
//        {
//             {-1,1,-1,},
//             {-1,1,-1,},
//             {-1,1,-1,},
//        },
//        {
//              {-1,-1,-1,},
//              {1,1,1,},
//              {-1,-1,-1,},
//        },
//        {
//              {-1,1,-1,},
//              {1,1,1,},
//              {-1,1,-1,},
//        },
//    };
//    int F1[6][3][3]={//模板二
//        {
//            {1,0,0,},
//            {0,1,0,},
//            {0,0,1,},
//        },
//        {
//            {1,0,1,},
//            {0,1,0,},
//            {1,0,1,},
//        },
//        {
//            {0,0,1,},
//            {0,1,0,},
//            {1,0,0,},
//        },
//        {
//            {0,1,0,},
//            {0,1,0,},
//            {0,1,0,},
//        },
//        {
//            {0,0,0,},
//            {1,1,1,},
//            {0,0,0,},
//        },
//        {
//            {0,1,0,},
//            {1,1,1,},
//            {0,1,0,},
//        },

//    };
//    Ft Feat[6];
//    Ft Feat1[6];
//    double timg[Nmax][Nmax];
//    double tmp_img[Nmax][Nmax];
//    //寻找特征值
//    for(int i = 0 ; i < 6 ; i ++ ){
//        Feat[i].cnt = Feat1[i].cnt = 0;
//        for(int j = 0 ; j < 3 ; j ++ ){
//            for(int k = 0 ; k < 3 ; k ++ ){
//                Feat[i].val[j][k] = F1[i][j][k];
//                Feat1[i].val[j][k] = F[i][j][k];
//                Feat[i].cnt += (F[i][j][k]==1)?1:0;
//                Feat1[i].cnt++;
//            }
//        }
//        for(int j = 0 ; j < len ; j ++ ){
//            for(int k = 0 ; k < len ; k ++ ){
//                timg[j][k] = tmp_img[j][k];
//            }
//        }

//        Node ans;
//        findvalues(timg,&Feat[i],&Feat1[i],len,&ans);
////        printf("Feat = %d cnt = %d\n",i+1,Feat[i].cnt);
//        //输出特征值
////        printf("第%d个特征值矩阵：\n");
//        ans.show();
//        for(int i = 0 ; i < 2 ; i ++ ){
//            for(int j = 0 ; j < 2 ; j ++ ){
//               arr[ii]=ans.val[i][j];
//                ii++;
//            }
//        }
//    }
}

void MainWindow::exitBtnResponded()
{
    m_pCamera->stop();
    m_pViewfinder->close();
}

void MainWindow::cameraImageCapture(int, QImage)
{
    qDebug()<<"******cameraImageCapture************";
    QString savepath =
    QFileDialog::getSaveFileName(this,"save Capture","Capture",
                 "Image png(*.png);;Image jpg(*.jpg);;Image bmp(*.bmp)");
    if(!savepath.isEmpty())
    {
        image.save(savepath);
    }
}

void MainWindow::capture()
{
    qDebug()<<"****************************";
         //m_pCamera->start();
        m_pImageCapture->capture();
}

void MainWindow::on_pushButton_carmera_clicked()
{

    m_pCamera->start();
}



void MainWindow::on_button2_clicked()
{

}

void MainWindow::on_pushButton_clicked()
{
    char s;
    s = compare();
    result = s;
    Form *myForm = new Form;
    myForm ->show();
    qDebug()<<"------------------------------识别图片-------------";
    if(s=='x'){
        qDebug()<<"识别为x";
    }if(s=='o'){
        qDebug()<<"识别为o";
    }if(s=='#'){
        qDebug()<<"无法识别";
    }
}
